﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

using Cabal.Kernel.DataSet;
using System.Net;
using System.IO;

namespace Cabal.Kernel.Output
{
    public class HttpRequestMission : MissionData
    {
        public HttpRequestMission(HttpWebRequest request,byte[] data)
        {
            _request = request;
            _data = data;
            setProxyFlag();
            SetState(MissionState.Unstarted);
        }

        HttpWebRequest _request;
        HttpWebResponse _response;
        byte[] _data;
        byte[] _recived;
        Exception _error;
        DateTime lastopt;

        static Uri testuri = new Uri("http://www.baidu.com");
        void setProxyFlag()
        {
            FlagSet.AddData(MissionData.Flag_SourceIP, GetSourceIP());
        }
        public string GetSourceIP()
        {
            string proxy;
            if (_request.Proxy != null)
                proxy = _request.Proxy.GetProxy(testuri).Authority;
            else
                proxy = MissionData.Flag_SourceIP_Self;

            return proxy;
        }

        public Uri GetRequestUri()
        {
            return _request.RequestUri;
        }
        public HttpRequestResult GetRequestResult()
        {
            MissionState state = GetState();

            if (state == MissionState.Succeed || state == MissionState.Failed)
            {
                HttpRequestResult result = new HttpRequestResult();
                result.data = _recived;
                result.response = _response;
                result.error = _error;
                return result;
            }
            else
            {
                throw new MissionStateException(this, "任务必须结束才可获取结果");
            }
        }
        public HttpRequestResult DoRequest()
        {
            MissionState state = GetState();
            if (state != MissionState.Unstarted)
            {
                throw new MissionStateException(this, "任务已经执行或完成,无法再次执行");
            }
            doRequest();
            return GetRequestResult();
        }

        //do request with setting final state but not start state
        protected void doRequest()
        {
            try
            {
                Stream streamRequest;
                Stream streamread;
                List<byte> result;

                streamRequest = _request.GetRequestStream(); //上行流
                for (int i = 0; i < _data.Length; i++)
                {
                    streamRequest.WriteByte(_data[i]);
                }
                streamRequest.Close();

                _response = _request.GetResponse() as HttpWebResponse; //获取回应

                streamread = _response.GetResponseStream(); //下行流
                result = new List<byte>(1024);
                while (streamread.CanRead)
                {
                    result.Add((byte)streamread.ReadByte());
                }
                streamread.Close();

                _recived = result.ToArray(); //结果存储
                SetState(MissionState.Succeed);
            }
            catch (Exception err)
            {
                _error = err;
                SetState(MissionState.Failed);
            }
            finally
            {
                lastopt = DateTime.Now;
            }
        }


        #region MissionData成员
        public override string GetMissionType()
        {
            return MissionData.MType_HttpRequest;
        }
        public override object GetResult()
        {
            return (object)GetRequestResult();
        }
        public override object DoWork()
        {
            return DoRequest() as object;
        }
        #endregion

        public override bool NeedCollect(int time)
        {
            MissionState state = GetState();
            if (state == MissionState.Succeed || state == MissionState.Failed)
            {
                TimeSpan ts = new TimeSpan(0, 0, 0, 0, time);
                if (DateTime.Now - lastopt > ts) //超过时限
                    return true;
                else
                    return false;
            }
            else
            {
                return false;
            }
        }
    }

    public class HttpRequestResult
    {
        public HttpWebResponse response;
        public byte[] data;
        public Exception error;
    }
}